package com.wgzx.modbus.entity.response;

import com.wgzx.modbus.constant.FunctionCode;
import com.wgzx.modbus.entity.ModbusRsp;
import io.netty.buffer.ByteBuf;
import lombok.Getter;

import java.util.BitSet;

/**
 * 请求报文：</br>
 * 功能码：0x01读线圈(按bit位读取) </br>
 * 起始地址：2个字节0x0000至0xFFFF </br>
 * 线圈数量：2个字节0x01至0x07D0 </br>
 *
 * 响应报文：</br>
 * 功能码：1个字节 0x01 </br>
 * 字节数：1个字节 值:N </br>
 * 线圈状态 N个字节 </br>
 * N＝输出数量/8，如果余数不等于0，那么N=N+1(请求10个bit位，如果不是8的倍数，则需要+1) </br>
 *
 * 错误响应：<br/>
 * 差错码：1个字节0x81 <br/>
 * 异常码：1个字节01或02或03或04 <br/>
 *
 * 测试报文：</br>
 * Rx:00 01(事务ID) 00 00(协议标识符) 00 06(报文长度) FF(单元标识符) 01(功能码) 00 00(起始位置偏移量) 00 0A(读取线圈数量) </br>
 * Tx:00 01(事务ID) 00 00(协议标识符) 00 05(报文长度) FF(单元标识符) 01(功能码) 02(数据长度) 45 02(线圈数据) </br>
 * BitSet bitSet = BitSet.valueOf(new byte[] {0x45, 0x02}); </br>
 * ReadCoilsResponse{byteCount=2, coilStatus={0, 2, 6, 9}}; </br>
 * 0x45=0100,0101 0x02=0000,0010，那么按照字节顺序，然后在从低位开始，就是(0,2,6,9)这个几个位置的值为true。</br>
 *
 * @author gexin
 */
@Getter
public class ReadCoilsResponse extends ModbusRsp {

    private short byteCount;
    private BitSet coilStatus;

    public ReadCoilsResponse(FunctionCode functionCode) {
        super(functionCode);
    }

    @Override
    public void decode(ByteBuf buffer) {
        //读取数据长度
        byteCount = buffer.readUnsignedByte();

        //解码出数据
        byte[] coils = new byte[byteCount];
        buffer.readBytes(coils);

        //转为bitset位图
        coilStatus = BitSet.valueOf(coils);
    }

    @Override
    public String toString() {
        return "ReadCoilsResponse{" + "byteCount=" + byteCount + ", coilStatus=" + coilStatus + '}';
    }
}
